/*
 * Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 * This file is part of e3ds.
 *
 * e3ds is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * e3ds is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with e3ds. If not, see <https://www.gnu.org/licenses/>.
 */

package heap

import "gitee.com/ameise84/e3ds/heap/compare"

func newHeapBase[T1 Integer, T2 compare.Ordered[T2]](size int, r compare.Result) heapBase[T1, T2] {
	return heapBase[T1, T2]{
		entities:      make([]*entity[T1, T2], 0, size),
		compareResult: r,
	}
}

type heapBase[T1 Integer, T2 compare.Ordered[T2]] struct {
	entities      []*entity[T1, T2]
	compareResult compare.Result
}

func (ts *heapBase[T1, T2]) Len() int { return len(ts.entities) }

func (ts *heapBase[T1, T2]) Less(i, j int) bool {
	r := ts.entities[i].ctx.Compare(ts.entities[j].ctx)
	return r == ts.compareResult || (r == compare.Equal && ts.entities[i].id < ts.entities[j].id)
}

func (ts *heapBase[T1, T2]) Swap(i, j int) {
	ts.entities[i], ts.entities[j] = ts.entities[j], ts.entities[i]
	ts.entities[i].index, ts.entities[j].index = i, j
}

func (ts *heapBase[T1, T2]) Push(x any) {
	item := x.(*entity[T1, T2])
	item.index = len(ts.entities)
	ts.entities = append(ts.entities, item)
}

func (ts *heapBase[T1, T2]) Pop() any {
	old := ts.entities
	n := len(old)
	x := old[n-1]
	ts.entities = old[0 : n-1]
	return x
}
